using System;
using System.Text;
using System.Runtime;
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;




enum SABattleResultType
{
	NEXT = 0,
	WIN,
	LOSE,
	TIMEOUT,
	
	COUNT
};


enum SABattleSessionType
{
	PVE = 0,
	PVP,
	
	COUNT
};


enum SABattleSessionCommandType
{
	ATTACK = 0,
	DEFENCE,
	MAGIC,
	STAY,
	ESCAPE,
	
	COUNT
};


enum SABattleSessionRow
{
	UNDER = 0,
	UP,
	
	COUNT
};


enum SABattleSessionSide
{
	SELF = 0,
	ENEMY,
	
	COUNT
};


enum SABattleSessionResultType
{
	HP = 0,
	MP,
	HPMP,
	MISS,
	PARRY,
	KILL,
	
	COUNT
};


[ StructLayout( LayoutKind.Sequential , Pack = 1 ) ]
public struct SABattleCreatureData
{
	public short	HP;
	public short	MAXHP;
	
	public byte		Level;
	public byte		Index;
	
	public byte		Role;
	public byte		Color;

	public byte		RidingPet;
	public byte		WeaponType;

	public int		ActionID;


	public void copyData( SABattleCreatureData data )
	{

	}

	public void copyDataFromPlayerData( SACreatureData data )
	{
		HP = data.Base.HP;
		MAXHP = data.Base.MAXHP;
		Level = data.Level;
		Role = data.Role;
		Color = data.Color;
		RidingPet = data.RidingPet;
		WeaponType = data.WeaponType;
	}

	public void updateAction()
	{
		ActionID = SARoleConfig.instance.getActionID( Role , Color , RidingPet , WeaponType );
	}

};


[ StructLayout( LayoutKind.Sequential , Pack = 1 ) ]
public struct SACreatureFightCommand
{
	public byte	Type;
	public byte	TargetRow;
	public byte	TargetIndex;
	public byte	unknow1;
};


[ StructLayout( LayoutKind.Sequential , Pack = 1 ) ]
public struct SABattleSessionCommand
{
	public SACreatureFightCommand cmd;

	public byte Side;
	public byte Row;
	public byte Index;
	public byte unknow1;
};



public class SABattleCreature : MonoBehaviour
{
	private SABattleCreatureMove creatureMove = new SABattleCreatureMove();
	private SACreatureAction creatureAction = null;

	private SABattlePos originalPos = new SABattlePos();
	private int originalDirection = (int)SAMapDirectionType.COUNT;

	private BoxCollider boxCollider = null;
	private LineRenderer lineRenderer = null;

	private bool bTarget = false;

	[ HideInInspector ] public SABattleCreatureData creatuerData = new SABattleCreatureData();
	
	[ HideInInspector ] public int actionID = 0;

	[ HideInInspector ] public SABattleSessionCommand command;

	[ HideInInspector ] public int normalStatus = (int)SANormalStatusType.NORMAL;
	[ HideInInspector ] public int battleStatus = (int)SABattleStatusType.NONE;


	static GameObject spriteObject = null;
	private static GameObject Create()
	{

		if ( spriteObject == null ) 
		{
			spriteObject = (GameObject)Resources.Load( "Prefabs/SABattleCreature" );
			DontDestroyOnLoad( spriteObject );
		}
		
		return (GameObject)Instantiate( spriteObject );
	}
	
	public static void DestoryCreature( GameObject obj )
	{
		Destroy( obj );
		
		SABattleCreature player = obj.GetComponent< SABattleCreature >();
		player.creatureMove = null;
		player.creatureAction.clearAction();
		player.creatureAction = null;
	}
	
	public static GameObject CreateCreature()
	{
		GameObject obj = Create();
		
		return obj;
	}


	void Awake()
	{
		initCreature();

	}

	public void initCreature()
	{
		creatureMove.owner = this;
		creatureMove.moveOverDelegate = onMoveOver;

		creatureAction = GetComponent< SACreatureAction >();
		creatureAction.actionOverDelegate = onActionOver;
		creatureAction.updateFrameDelegate = onUpdateFrame;

		boxCollider = GetComponent< BoxCollider >();
		lineRenderer = GetComponent< LineRenderer >();

		enableTarget( false );
	}

	public void initCreatureCommon( byte s , byte r , byte i  )
	{
		command.Side = s;
		command.Row = r;
		command.Index = i;
	}

	public void updateAction()
	{
		actionID = SARoleConfig.instance.getActionID( creatuerData.Role , creatuerData.Color , creatuerData.RidingPet , creatuerData.WeaponType );
		
		creatureAction.setActionID( actionID );
		creatureAction.playAction();
	}

	public void setActionID( int a )
	{
		actionID = a;

		creatureAction.setActionID( actionID );
		creatureAction.playAction();
	}

	public void setDirection( int d )
	{
		creatureAction.setDirection( d );
	}

	public int getDirection()
	{
		return creatureAction.direction;
	}

	public int getAction()
	{
		return creatureAction.actionType;
	}

	public void setAction( int a , int d = GameDefine.INVALID_ID )
	{
		if ( d == GameDefine.INVALID_ID ) 
		{
			d = creatureAction.direction;
		}

		creatureAction.playAction( a , d );
	}

	public void setDelay( float d )
	{
		creatureAction.setDelay( d );
	}

	public void movePosReal()
	{
		transform.localPosition = new Vector3( creatureMove.pos.x , 
			                                      creatureMove.pos.y ,
			                                      GameDefine.getZ( creatureMove.pos.y ) );
		

	}
	
	public void endMoving()
	{
		creatureMove.endMoving();
	}
		
	public SABattlePos getPos()
	{
		return creatureMove.pos;
	}

	public SABattlePos getAdvancePos()
	{
		return creatureMove.advancePos;
	}

	public SABattlePos getBackPos()
	{
		return creatureMove.backPos;
	}


	public void setOriginalDirection( int d )
	{
		originalDirection = d;
		setDirection( d );
	}
	public int getOriginalDirection()
	{
		return originalDirection;
	}
	public int getReverseOriginalDirection()
	{
		return SAMapDirection.getReverseDirection( originalDirection );
	}

	public SABattlePos getOriginalPos()
	{
		return originalPos;
	}
	public void setOriginalPos( float x , float y , float ax , float ay )
	{
		originalPos.setPos( x , y );

		creatureMove.setPos( x , y );
		creatureMove.setAdvancePos( x + ax * SAMapGrid.GridXHalf , y + ay * SAMapGrid.GridYHalf );
		creatureMove.setBackPos( x - ax * SAMapGrid.GridXHalf * 0.4f , y - ay * SAMapGrid.GridYHalf * 0.4f );
		
		movePosReal();
	}

	public void setMoveSpeed( float s )
	{
		creatureMove.setMoveSpeed( s );
	}

	public void startMove( float x , float y , float t , bool b = true )
	{
		creatureMove.startMove( x , y , t , b );
	}

	public void enableTarget( bool b )
	{
		bTarget = b;
		
		boxCollider.enabled = b;
		lineRenderer.enabled = b;
	}


	public void onTouchUp()
	{
		SABattleCommandManager.instance.atkCommand( command );
	}


	void onUpdateFrame( int action , float frame , SATexture texture )
	{ 
		if ( bTarget ) 
		{
			boxCollider.center = new Vector3( texture.px + texture.w * 0.5f , -texture.py - texture.h * 0.5f , 0.0f );
			boxCollider.size = new Vector3( texture.w , texture.h , 0.0f );
			
			float offset = 2;
			lineRenderer.SetPosition( 0 , new Vector3( texture.px - offset , -texture.py + offset , 0.0f ) );
			lineRenderer.SetPosition( 1 , new Vector3( texture.px + texture.w + offset , -texture.py + offset , 0.0f ) );
			lineRenderer.SetPosition( 2 , new Vector3( texture.px - offset , -texture.py + offset , 0.0f ) );
			
			lineRenderer.SetPosition( 3 , new Vector3( texture.px - offset , -texture.py - texture.h - offset , 0.0f ) );
			lineRenderer.SetPosition( 4 , new Vector3( texture.px - offset , -texture.py + offset, 0.0f ) );
			lineRenderer.SetPosition( 5 , new Vector3( texture.px - offset , -texture.py - texture.h - offset , 0.0f ) );
			
			lineRenderer.SetPosition( 6 , new Vector3( texture.px + texture.w + offset , -texture.py - texture.h - offset , 0.0f ) );
			lineRenderer.SetPosition( 7 , new Vector3( texture.px - offset , -texture.py - texture.h - offset , 0.0f ) );
			lineRenderer.SetPosition( 8 , new Vector3( texture.px + texture.w + offset , -texture.py - texture.h - offset , 0.0f ) );
			
			lineRenderer.SetPosition( 9 , new Vector3( texture.px + texture.w + offset , -texture.py + offset , 0.0f ) );
			lineRenderer.SetPosition( 10 , new Vector3( texture.px + texture.w + offset , -texture.py - texture.h - offset , 0.0f ) );
			lineRenderer.SetPosition( 11 , new Vector3( texture.px + texture.w + offset , -texture.py + offset , 0.0f ) );
			
			lineRenderer.SetPosition( 12 , new Vector3( texture.px - offset , -texture.py + offset , 0.0f ) );
		}

	}

	void onMoveOver()
	{
		SABattleResultManager.instance.onMoveOver( this );
	}
	
	void onActionOver( int action )
	{
		SABattleResultManager.instance.onActionOver( this , action );
	}


	void Update()
	{
		creatureMove.updateMove( Time.deltaTime );
	}

}
